#include "task.h"

#include "timer.h"
TASK_CB obj_task = {
	.name = "obj_task",
};
TASK_CB currentTask = {0};

int task_create(TASK_CB *task, char *name, void (*task_ctrl)(TASK_CTRL ctrl_type, void *param), void (*task_run)(void))
{
	TASK_CB *task_t = NULL;
	if (task == NULL)
		return TASK_INVALID;
	task_t = task_find(name);
	if (task_t != NULL)
	{
		task_start(task);
		return TASK_RUN;
	}

	memset(task, 0, sizeof(TASK_CB));
	strncpy(task->name, name, TASK_NAME_MAXLEN - 1);
	task->Task_RunState = TASK_READY;
	task->task_ctrl = task_ctrl;
	task->task_run = task_run;
	list_init(&task->task_list);
	list_insert_after(&obj_task.task_list, &task->task_list);
	return TASK_READY;
}
TASK_CB *task_find(char *name)
{
	TASK_CB *task = NULL;

	list *p = &obj_task.task_list;
	while (p->next != &obj_task.task_list)
	{
		task = (TASK_CB *)GET_DEVICE(p->next, TASK_CB, task_list);
		if (task != NULL)
		{
			if (!strncmp(name, task->name, TASK_NAME_MAXLEN))
			{
				return task;
			}
		}
		p = p->next;
	}
	return NULL;
}
void task_start(TASK_CB *task)
{
	if (task != 0)
	{
		if (task->Task_RunState != TASK_INVALID)
		{
			task->Task_RunState = TASK_RUN;
			task->Task_StartTime = timer_GetTick();
		}
	}
}
void task_stop(TASK_CB *task)
{
	if (task != 0)
	{
		if (task->Task_RunState != TASK_INVALID)
		{
			task->Task_RunState = TASK_STOP;
			task->Task_RunTime = (uint32_t)(timer_GetTick() - task->Task_StartTime);
		}
	}
}
void task_delete(TASK_CB *task)
{
	if (task != 0)
	{
		if (task->Task_RunState != TASK_INVALID)
		{
			task->Task_RunTime = (uint32_t)(timer_GetTick() - task->Task_StartTime);
			list_remove(&task->task_list);
		}
	}
}

void task_ctrl(char *name, TASK_CTRL ctrl_type, void *param)
{
	TASK_CB *Task_t = NULL;
	if (name == 0)
	{
		list *p = &obj_task.task_list;
		while (p->next != &obj_task.task_list)
		{
			Task_t = (TASK_CB *)GET_DEVICE(p->next, TASK_CB, task_list);
			if (Task_t != NULL)
			{
				if (Task_t->task_ctrl != 0)
					Task_t->task_ctrl(ctrl_type, param);
				break;
			}
		}
	}
	else
	{
		Task_t = task_find(name);
		if (Task_t != 0)
		{
			if (Task_t->task_ctrl != 0)
				Task_t->task_ctrl(ctrl_type, param);
		}
	}
}
void Task_Run(void)
{
	TASK_CB *Task_t = NULL;
	list *p = &obj_task.task_list;
	while (p->next != &obj_task.task_list)
	{
		Task_t = (TASK_CB *)GET_DEVICE(p->next, TASK_CB, task_list);
		if (Task_t != NULL)
		{
			if (Task_t->Task_RunState == TASK_RUN)
			{
				if (Task_t->task_run != 0)
				{
					memcpy(&currentTask, Task_t, sizeof(TASK_CB));
					Task_t->Task_RunTime = (uint32_t)(timer_GetTick() - Task_t->Task_StartTime);
					Task_t->task_run();
				}
			}
		}

		p = p->next;
	}
}
static int task_autoInit(void)
{
	list_init(&obj_task.task_list);
	return 0;
}
BOARD_INIT(task_autoInit);
